#include "logcatclient.h"
#include <QDomDocument>
#include <QDebug>

void LogCatClient::reconnect()
{
    qDebug()<< "client reconnect!";
    if( isConnected )
    {
        m_timer.stop();
    }else
    {
        connectToHost(m_host, m_port);
        if(!m_timer.isActive())
            m_timer.start();
    }
}

void LogCatClient::sendData(QByteArray data)
{
    int len = data.length();
    char lenchar[4]={0};
    memcpy(lenchar, &len, 4);
    write(&lenchar[0], 1);
    write(&lenchar[1], 1);
    write(&lenchar[2], 1);
    write(&lenchar[3], 1);
    write(data);
}

void LogCatClient::sendTestMsg(const QString &msg)
{
    QByteArray data = msg.toLatin1();
    sendData(data);
}

LogCatClient::LogCatClient(QObject *parent) :
    QTcpSocket(parent)
{
    connect(this, SIGNAL(readyRead()), SLOT(readLog()));
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleError(QAbstractSocket::SocketError)));
    connect(this, SIGNAL(connected()), SLOT(_slotConnected()));
    connect(this,SIGNAL(disconnected()),SLOT(_slotDisConnected()));
    isConnected = false;
    m_timer.setInterval(1000);
    m_timer.setSingleShot(false);
    m_timer.stop();
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(reconnect()));

//    reconnect();
}

void LogCatClient::readLog(){
    m_dataBuffer.append(readAll());
    int len;
    char ch[4];
    QByteArray temp;
    QDomDocument doc("log");
    QDomElement docElem;
    LogItem log;
    QDomNode n;
    while(1)
    {
        ch[0] = m_dataBuffer[0];
        ch[1] = m_dataBuffer[1];
        ch[2] = m_dataBuffer[2];
        ch[3] = m_dataBuffer[3];
        memcpy(&len, ch, 4);
        if(len > 4096)
        {
            m_dataBuffer.clear();
            return;
        }
        if(m_dataBuffer.length() < len + 4)
            return;
        m_dataBuffer.remove(0, 4);
        temp = m_dataBuffer.left(len);
        m_dataBuffer.remove(0, len);

        qDebug()<< "\nGet:----------------------\n";

        if(!doc.setContent(temp))
        {
            m_dataBuffer.clear();
            qWarning("Content Error XML！");
            qDebug()<< temp;
            return;
        }

        //    int len = m_dataBuffer[0] * 10 + m_dataBuffer[1];
        qDebug() <<"\n" << doc.toString(2);

        docElem = doc.documentElement();
        log.type = docElem.attribute("type", "");
        n = docElem.firstChild();

        while(!n.isNull()) {
            QDomElement e = n.toElement(); // try to convert the node to an element.
            if(!e.isNull()) {
                if(e.tagName() == "category")
                {
                    log.category = e.text();
                }else if(e.tagName() == "file")
                {
                    log.file = e.text();
                }else if(e.tagName() == "function")
                {
                    log.function = e.text();
                }else if(e.tagName() == "line")
                {
                    log.line = e.text().toInt();
                }else if(e.tagName() == "msg")
                {
                    log.msg = e.text();
                }else if(e.tagName() == "version")
                {
                    log.version = e.text();
                }else
                {
                    qWarning() << "unsupport tag:" << e.tagName();
                }
            }
            n = n.nextSibling();
        }
        emit newLog(log);
    }
}
void LogCatClient::handleError(QAbstractSocket::SocketError socketError)
{
    qDebug()<< "ERROR:" << errorString();
}
void LogCatClient::start(const QString host, int port)
{
    m_host = host;
    m_port = port;
    m_running = true;
    LogItem log;
    log.msg = "-------------start-------------";
    log.type = "d";
    emit newLog(log);
    reconnect();
}

void LogCatClient::_slotConnected(void)
{
    qDebug()<< "after connected";
    isConnected = true;
    LogItem log;
    log.msg = "-------------connected-------------";
    log.type = "d";
    emit newLog(log);
    emit isConnectedChanged();

}

void LogCatClient::_slotDisConnected(void)
{
    isConnected = false;
    emit isConnectedChanged();
    LogItem log;
    log.msg = "-------------disconnected!-------------";
    log.type = "e";
    emit newLog(log);
    if(m_running)
        reconnect();
}

void LogCatClient::stop()
{
    m_running = false;
    LogItem log;
    log.msg = "-------------stop!-------------";
    log.type = "d";
    emit newLog(log);
    close();
}
